<?php
/**
 * 验证码类。
 */
class VeriCode {
	private $font; // 指定的字体
	private $fontsize; // 指定字体大小
	private $charset; // 可用字符集
	private $width; // 图片宽度
	private $height; // 图片高度
	private $codelen; // 验证码长度
	private $code; // 验证码

	public function __construct()
	{
		// 注意：这里使用到的字体文件，在 Windows 下会被锁住而无法删除，在 Linux 下没有这个问题。
		// 参考：https://bugs.php.net/bug.php?id=24450
		$this->font = dirname(__FILE__) . '/vericode.ttf';
		$this->fontsize = 20;
		$this->charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';
		$this->width = 130;
		$this->height = 40;
		$this->codelen = 4;
		$this->generateCode();
	}

	/**
	 * 随机生成验证码。
	 */
	public function generateCode()
	{
		$this->code = '';
		$_len = strlen($this->charset) - 1;
		for ($i = 0; $i < $this->codelen; $i++) {
			$this->code .= $this->charset[mt_rand(0, $_len)];
		}
		return $this->getCode();
	}

	/**
	 * 输出验证码图片。
	 */
	public function draw()
	{
		// 背景图片
		$img = imagecreatetruecolor($this->width, $this->height);
		$color = imagecolorallocate($img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
		imagefilledrectangle($img, 0, $this->height, $this->width, 0, $color);

		// 雪花干扰
		for ($i = 0; $i < 100; $i++) {
			$color = imagecolorallocate($img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
			imagestring($img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
		}

		// 验证码文字
		$_x = $this->width / $this->codelen;
		for ($i = 0; $i < $this->codelen; $i++) {
			$color = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
			imagettftext($img, $this->fontsize, mt_rand(- 30, 30), $_x * $i + mt_rand(5, 10), $this->height / 1.4, $color, $this->font, $this->code[$i]);
		}

		// 线条干扰
		for ($i = 0; $i < 6; $i++) {
			$color = imagecolorallocate($img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
			imageline($img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
		}

		// 输出图片
		header('Content-type: image/png');
		imagepng($img);
		imagedestroy($img);
	}

	/**
	 * 取验证码。
	 */
	public function getCode()
	{
		return strtolower($this->code);
	}
}
